import UIKit

protocol Test {
    
}
print(type(of: Test.self))

struct SBTest: Test {
    
}
let s: Test = SBTest()
print(type(of: s))

func sum<T: Test>(param: T) {
    print(type(of: param))
}

sum(param: s)


class ClassA {
    var value = 10
    func testType(value: ClassA.Type) {
        
    }
}
let a1: ClassA = ClassA()
print(type(of: a1))
print(type(of: ClassA.self))

let a: ClassA = ClassA()
a.testType(value: ClassA.self)

let a2: ClassA = ClassA()
print(type(of: ClassA.self))


func printGenericInfo<T>(_ value: T) {
    let t = type(of: value)
    print("'\(value)' of type '\(t)'")
}

protocol P {}
extension String: P {}

let stringAsP: P = "Hello!"
printGenericInfo(stringAsP)
// 'Hello!' of type 'P'
